#include "NeoCalendar.h"
#include "NeoIcon.h"
#include "NeoPushButton.h"
#include "NeoScrollBar.h"
#include "common/NeoBaseListView.h"
#include "common/NeoCalendarDelegate.h"
#include "common/NeoCalendarHeaderDelegate.h"
#include "common/NeoCalendarHeaderModel.h"
#include "common/NeoCalendarMask.h"
#include "common/NeoCalendarModel.h"
#include "private/NeoCalendarPrivate.h"
#include <QLayout>

NEO_PUBLIC_PROPERTY_CREATE_CPP(NeoCalendar, QColor, BackgroundColor)
NEO_PUBLIC_PROPERTY_CREATE_CPP(NeoCalendar, QColor, ToDayItemColor)
NEO_PUBLIC_PROPERTY_CREATE_CPP(NeoCalendar, QColor, ItemHoverColor)
NEO_PUBLIC_PROPERTY_CREATE_CPP(NeoCalendar, QColor, ItemSelectedColor)
NEO_PUBLIC_PROPERTY_CREATE_CPP(NeoCalendar, QColor, ItemSelectedBorderColor)

NeoCalendar::NeoCalendar(QWidget *parent)
    : QWidget(parent), d_ptr(new NeoCalendarPrivate())
{
    NEO_PUBLIC_POINT(NeoCalendar)
    d->q_ptr = this;

    d->pCalendarMask = new NeoCalendarMask(this, true);
    d->pCalendarMask->hide();

    d->pTitleButton = new NeoPushButton(this);
    d->pTitleButton->setButtonStyle(NeoPushButtonType::ButtonTextOnly);
    d->pTitleButton->setHoverBackgroundColor(Qt::lightGray);
    d->pPrevButton = new NeoPushButton(this);
    d->pPrevButton->setButtonStyle(NeoPushButtonType::ButtonIconOnly);
    d->pPrevButton->setHoverBackgroundColor(Qt::lightGray);
    d->pPrevButton->setPressedBackgroundColor(Qt::lightGray);
    d->pPrevButton->setIcon(NeoIconInstance->getNeoIcon(NeoIconType::FontAwesomeSolid::ChevronUp, Qt::black, 16, 16, 16));
    d->pNextButton = new NeoPushButton(this);
    d->pNextButton->setButtonStyle(NeoPushButtonType::ButtonIconOnly);
    d->pNextButton->setHoverBackgroundColor(Qt::lightGray);
    d->pNextButton->setPressedBackgroundColor(Qt::lightGray);
    d->pNextButton->setIcon(NeoIconInstance->getNeoIcon(NeoIconType::FontAwesomeSolid::ChevronDown, Qt::black, 16, 16, 16));

    QHBoxLayout *titleLayout = new QHBoxLayout();
    titleLayout->setContentsMargins(0, 0, 0, 0);
    titleLayout->setSpacing(0);
    titleLayout->addWidget(d->pTitleButton);
    titleLayout->addWidget(d->pPrevButton);
    titleLayout->addWidget(d->pNextButton);
    titleLayout->setStretch(0, 8);
    titleLayout->setStretch(1, 1);
    titleLayout->setStretch(2, 1);

    d->pHeaderView = new NeoBaseListView(this);
    d->pHeaderView->setModel(d->pHeaderModel);
    d->pHeaderView->setItemDelegate(d->pHeaderDelegate);
    d->pHeaderView->setViewMode(QListView::IconMode);
    d->pHeaderView->setFrameShape(QFrame::NoFrame);
    d->pHeaderView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    d->pHeaderView->setSelectionMode(QAbstractItemView::NoSelection);
    d->pHeaderView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    d->pHeaderView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    d->pCalendarView = new NeoBaseListView(this);
    d->pCalendarView->setModel(d->pCalendarModel);
    d->pCalendarView->setItemDelegate(d->pCalendarDelegate);
    d->pCalendarView->setUniformItemSizes(true);
    d->pCalendarView->setViewMode(QListView::IconMode);
    d->pCalendarView->setAutoScroll(false);
    d->pCalendarView->setSpacing(0);
    d->pCalendarView->setContentsMargins(0, 0, 0, 0);
    d->pCalendarView->setResizeMode(QListView::Adjust);
    d->pCalendarView->setFrameShape(QFrame::NoFrame);
    d->pCalendarView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    d->pCalendarView->setSelectionMode(QAbstractItemView::NoSelection);

    NeoScrollBar *verticalScrollBar = new NeoScrollBar(Qt::Vertical, d->pCalendarView);
    d->pCalendarView->setVerticalScrollBar(verticalScrollBar);
    NeoScrollBar *scrollBar = new NeoScrollBar(d->pCalendarView, Qt::Vertical);
    scrollBar->setExtent(0);
    scrollBar->setWheelSpeed(10);

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setContentsMargins(5, 5, 5, 5);
    layout->setSpacing(0);
    layout->addLayout(titleLayout);
    layout->addWidget(d->pHeaderView);
    layout->addWidget(d->pCalendarView);
    layout->setStretch(0, 1);
    layout->setStretch(1, 1);
    layout->setStretch(2, 8);

    connect(d->pTitleButton, &NeoPushButton::clicked, d, &NeoCalendarPrivate::onTitleButtonClicked);
    connect(d->pPrevButton, &NeoPushButton::clicked, d, &NeoCalendarPrivate::onPrevButtonClicked);
    connect(d->pNextButton, &NeoPushButton::clicked, d, &NeoCalendarPrivate::onNextButtonClicked);
    connect(d->pCalendarView, &NeoBaseListView::clicked, d, &NeoCalendarPrivate::onDateIndexClicked);
    connect(scrollBar, &NeoScrollBar::valueChanged, this, [=]()
            {
        NEO_PUBLIC_POINT(NeoCalendar)
        d->updateCenterIndex(); });
}

NeoCalendar::~NeoCalendar() = default;

void NeoCalendar::showEvent(QShowEvent *event)
{
    NEO_PUBLIC_POINT(NeoCalendar)
    d->changeDisplayMode(NeoCalendarType::DayView);
    d->scrollToDate(QDate::currentDate(), false);
    d->pCalendarView->setCurrentIndex(d->pCalendarModel->getIndexFromDate(QDate::currentDate()));
    return QWidget::showEvent(event);
}